import unittest

from google.appengine.api import memcache
from google.appengine.ext import ndb
from google.appengine.ext import testbed
from google.appengine.ext import deferred

from server_main import *
from recalc_statistic import *
from statistics.word_statistic import *

import constants

json_string = '''
{
    "rounds": [
        {
            "words": [
                {
                    "text": "Word1",
                    "owner": "Owner",
                    "result": "GUESS",
                    "time": 5.6
                },
                {
                    "text": "Word2",
                    "owner": "Owner",
                    "result": "GUESS",
                    "time": 5.6
                }
            ],
            "player1": "Player_1",
            "player2": "Player_2"
        }
    ]
}
'''

json_string_1 = '''
{
    "rounds": [
        {
            "words": [
                {
                    "text": "Word1",
                    "owner": "Owner",
                    "result": "PUT_BACK",
                    "time": 1.6
                },
                {
                    "text": "Word1",
                    "owner": "Owner",
                    "result": "FAIL",
                    "time": 5.6
                },
                {
                    "text": "Word2",
                    "owner": "Owner",
                    "result": "PUT_BACK",
                    "time": 11
                },
                {
                    "text": "Word",
                    "owner": "Owner",
                    "result": "TIME_OUT",
                    "time": 20
                }
            ],
            "player1": "Player_1",
            "player2": "Player_2"
        },
        {
            "words": [
                {
                    "text": "Word",
                    "owner": "Owner",
                    "result": "PUT_BACK",
                    "time": 5.6
                },
                {
                    "text": "Word",
                    "owner": "Owner",
                    "result": "FAIL",
                    "time": 18
                },
                {
                    "text": "Word2",
                    "owner": "Owner",
                    "result": "GUESS",
                    "time": 20
                }
            ],
            "player1": "Player_2",
            "player2": "Player_1"
        }
    ],
    "words_in_hat" : [
        {
            "owner" : "Vasya",
            "text" : "cat"
        },
        {
            "owner" : "Petya_LOH",
            "text" : "dog"
        },
        {
            "owner": "Owner",
            "text": "Word1"
        }
    ],
    "remote_id": 102
}
'''


class RecalcStatisticTest(unittest.TestCase):
    def setUp(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_taskqueue_stub()
        self.taskqueue_stub =\
            self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME)
        constants.WORD_STATISTIC_QUEUE = 'default'

    def make_post_request(self, url, data, expected_response_code=200):
        request = webapp2.Request.blank(url, POST=data)
        response = request.get_response(application)
        self.assertEqual(response.status_int, expected_response_code)

    def test_statistic_adding(self):
        self.game_history = json_to_game_history(json_string)
        self.game_history.put()
        self.game_history.add_to_statistic()
        self.game_history = json_to_game_history(json_string_1)
        self.game_history.add_to_statistic()
        rec_all_stat = recalc_statistic.RecalcAllStatistic()
        rec_all_stat.get()
        tasks = self.taskqueue_stub.get_filtered_tasks()
        self.assertEqual(1, len(tasks))
        self.assertEqual(tasks[0].url, '/recalc_all_stat_from_queue')
        self.taskqueue_stub.FlushQueue('default')
        #print tasks[0]
        self.make_post_request(tasks[0].url, tasks[0].payload)
        #recalc_add_stat_q = RecalcAllStatisticFromQueue()
        #recalc_add_stat_q.post()

        tasks = self.taskqueue_stub.get_filtered_tasks()
        self.taskqueue_stub.FlushQueue('default')

        self.assertEqual(1, len(tasks))
        self.assertEqual(tasks[0].url, '/add_all_stat')
        add_all_stat = AddAllStatistic()
        add_all_stat.post()
        tasks = self.taskqueue_stub.get_filtered_tasks()
        self.taskqueue_stub.FlushQueue('default')
        self.assertEqual(4, len(tasks))
        for i in range(3):
            self.make_post_request(tasks[i].url, tasks[i].payload)
        self.make_post_request(tasks[3].url, tasks[3].payload)
        tasks = self.taskqueue_stub.get_filtered_tasks()

        self.assertEqual(len(list(WordStatistic.query())), 2)
        self.assertEqual(len(list(WordStatistic.query().filter(
            WordStatistic.word == 'Word1'))), 1)
        self.assertEqual(len(list(WordStatistic.query().filter(
            WordStatistic.word == 'Word2'))), 1)
        word_stat_1 = WordStatistic.query().filter(
            WordStatistic.word == 'Word1').get()
        word_stat_2 = WordStatistic.query().filter(
            WordStatistic.word == 'Word2').get()
        self.assertEqual(word_stat_1.word, "Word1")
        self.assertEqual(word_stat_2.word, "Word2")
        self.assertEqual(len(word_stat_1.hist_ttime), 1)
        self.assertEqual(len(word_stat_2.hist_ttime), 1)
        self.assertEqual(word_stat_1.hist_ttime[0], TTimeToCnt(time_sec=6,
                                                               cnt_guess=1))
        self.assertEqual(word_stat_2.hist_ttime[0], TTimeToCnt(time_sec=0,
                                                               cnt_guess=1))

        self.assertEqual(len(word_stat_1.hist_ltime_nattempt), 1)
        self.assertEqual(len(word_stat_2.hist_ltime_nattempt), 1)
        self.assertEqual(word_stat_1.hist_ltime_nattempt[0],
                         LTimeAttemptNToCnt(time_sec=6, cnt_guess=1,
                                            num_attempts=1))
        self.assertEqual(word_stat_2.hist_ltime_nattempt[0],
                         LTimeAttemptNToCnt(time_sec=0, cnt_guess=1,
                                            num_attempts=1))

    def tearDown(self):
        self.testbed.deactivate()


if __name__ == '__main__':
    unittest.main()
